Skip to content

feat(usage): track logins per user with date range filter#797

Open
ismaeldosil wants to merge 2 commits intodevelopfrom
feature/login-tracking
Open

feat(usage): track logins per user with date range filter#797
ismaeldosil wants to merge 2 commits intodevelopfrom
feature/login-tracking

Conversation

@ismaeldosil
Copy link
Copy Markdown
Collaborator

Summary

Implements per-user login tracking with a configurable date-range filter on the All Users dashboard. Existing lastLogin field only stored the most recent login (overwritten on each signin); this adds a loginEvents collection capturing one document per signin so administrators can see usage frequency.

Closes CHALK-110, CHALK-111, CHALK-112, CHALK-113, CHALK-114.

Changes

Backend (Firebase.tsx)

  • firebaseEmailSignIn writes a doc to a new loginEvents collection on every successful login ({ userId, timestamp }). The existing lastLogin field update is preserved for backward compatibility.
  • New method getUsersLoginCounts(start, end): single batch query against loginEvents filtered by timestamp, builds Map<userId, count> in memory. Same optimized pattern as getUsersLastAction().

UI (AllUsersTable.tsx, AllUsersPage.tsx)

  • Date range picker (@material-ui/pickers, already in deps) with quick presets: Last 7d / 30d / 90d.
  • New Logins column with numeric sort, alongside the existing Last Login column (different info — both useful).
  • Default range: last 30 days.
  • CSV export includes the login count with a date-stamped header (e.g. Logins (Apr 8 – May 8)).

State management

  • AllUsersPage loads users and counts in parallel (Promise.all) on mount.
  • Range changes refetch only getUsersLoginCounts (users are not re-queried).

Architectural notes

  • Mirrors CHALK-090 (Last Action) pattern — proven, in production since January.
  • No Firestore rules update needed — existing rules permit authenticated users to write.
  • No Cloud Functions added → no IAM permission constraints.
  • Cost: ~600 users × ~2 logins/day ≈ 1.2k writes/day. Well within free tier.

⚠️ Historical data limitation

Login counts begin from the deploy date forward. Past logins were never captured as discrete events — only the most recent was stored (and overwritten). This will be communicated to the client on delivery.

Test plan

  • Local Firebase emulator: sign in multiple times, verify docs created in loginEvents
  • All Users page: verify Logins column shows correct count for current admin
  • Change date range / use presets: counts update without re-loading users list
  • Sort by Logins column ascending and descending
  • CSV export: header includes formatted date range, count column populated
  • Staging deploy: smoke test with seeded data
  • Production deploy + verification

- Backend: write loginEvents doc on each signin (preserves lastLogin)
- Backend: getUsersLoginCounts(start, end) batch aggregation
- UI: date range picker on All Users dashboard with 7d/30d/90d presets
- UI: new Logins column with sort, alongside existing Last Login
- CSV export includes login count for selected range
- Default range: last 30 days

Closes CHALK-110
Closes CHALK-111
Closes CHALK-112
Closes CHALK-113
Closes CHALK-114
The /LeadersAllUsers route also renders <AllUsersTable> and was missing the new required props introduced for login tracking. Adds parallel load via Promise.all and a range-change handler matching the AllUsersPage pattern.

Closes CHALK-115
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant